package com.example.consumer_order_ribbon_hystrix_thread_isolation.Controller;

import com.example.consumer_order_ribbon_hystrix_thread_isolation.model.UserInf;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/order/user/getById")
    @ResponseBody
    /**
     * 部分注解意思如下：
     * CommandGroupKey：配置全局唯一标识服务分组的名称，比如，库存系统就是一个服务分
     * 组。当我们监控时，相同分组的服务会聚合在一起，必填选项。
     * CommandKey：配置全局唯一标识服务的名称，比如，库存系统有一个获取库存服务，那么
     * 就可以为这个服务起一个名字来唯一识别该服务，如果不配置，则默认是简单类名。
     * ThreadPoolKey：配置全局唯一标识线程池的名称，相同线程池名称的线程池是同一个，如
     * 果不配置，则默认是分组名，此名字也是线程池中线程名字的前缀。
     * ThreadPoolProperties：配置线程池参数：
     *      coreSize配置核心线程池大小和线程池最大大小，默认是10。
     *      keepAliveTimeMinutes是线程池中空闲线程生存时间（如果不进行动态配置，那么是没 有任何作用的），
     *      maxQueueSize配置线程池队列最大大小，
     *      queueSizeRejectionThreshold限定当前队列大小，即实际队列大小由这个参数决定，通过改变queueSizeRejectionThreshold可以实现动态队列大小调整。
     *      CommandProperties：配置该命令的一些参数，如executionIsolationStrategy配置执行隔离策略，默认是使用线程隔离，此处我们配置为THREAD，即线程池隔离。
     * 此处可以粗粒度实现隔离，也可以细粒度实现隔离，如下所示。
     * 服务分组+线程池：粗粒度实现，一个服务分组/系统配置一个隔离线程池即可，不配置线
     * 程池名称或者相同分组的线程池名称配置为一样。
     * 服务分组+服务+线程池：细粒度实现，一个服务分组中的每一个服务配置一个隔离线程
     * 池，为不同的命令实现配置不同的线程池名称即可。
     * 混合实现：一个服务分组配置一个隔离线程池，然后对重要服务单独设置隔离线程池。
     *
     * 视屏时间1:53:00左右
     * */

    /**
     * 注意：只要使用@HystrixCommand注解，就默认使用了线程池，默认线程数为10。
     * 例：当总共同时有12个请求产生，最后两个请求会被自动降级处理。
     * */
    @HystrixCommand(fallbackMethod = "fallback",
            groupKey = "orderUserGroup",
            threadPoolKey = "orderUserIdThreadPool",
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "2"),
                    @HystrixProperty(name = "maxQueueSize", value = "2"),
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "1")})
    public Object getUserById(String id) {
        System.out.println("--------------------" + id + "--------------");
        String url = "http://eureka-user/user/getById?id=" + id;
//        String url = "http://EUREKA_USER/user/getById?id=" + id;
//        String url = "http://localhost:8081/user/getById?id=" + id;
        return restTemplate.getForObject(url, Object.class);
    }

    public Object fallback(String id) {
        UserInf userInf = new UserInf();
        userInf.setId(-1);
        userInf.setAge(100);
        userInf.setName("fallback");
        return userInf;
    }

}
